<?php
	//开启session
	session_start();
	require_once('eloquent.php');
	 /* 检查是否为开发环境并设置是否记录错误日志 */
    function setReporting(){
        if (IS_DEBG == true) {
            error_reporting(E_ALL & ~E_NOTICE);
            ini_set('display_errors','On');
        } else {
            error_reporting(E_ALL);
            ini_set('display_errors','Off');
            ini_set('log_errors','On');
            ini_set('error_log',ROOT.DS.'logs' .DS. 'error.log');
        }
    }

	//php防注入和XSS攻击通用过滤.  
	$_GET   && safeFilter($_GET);
	$_POST   && safeFilter($_POST);
	$_COOKIE  && safeFilter($_COOKIE);
 

    /**
     * 过滤参数
     * @param string $str 接受的参数
     * @return string
     */
    function _safeFilter($str)
    {
        $arr = array(
                "/<(\\/?)(script|i?frame|style|html|body|title|link|meta|object|\\?|\\%)([^>]*?)>/isU",
                "/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU"
        );
        $str = preg_replace($arr,'',$str);
        return $str;
    }
     
    /**
     * 过滤接受的参数或者数组,如$_GET,$_POST,$_COOKIE 
     * @param array|string $arr 接受的参数或者数组
     * @return array|string
     */
    function safeFilter(&$arr)
    {
        if(is_array($arr)){
            foreach($arr as $k => $v){
                $arr[$k] = _safeFilter($v);
            }
        }else{
            $arr = _safeFilter($v);
        }
        return $arr;
    }
	
	//启用SQL注入
	function _safeParams($str){
		$arr = array(
             "/\'|\"|\/\*|\*|\.\.\/|\.\//is"
        );
        $str = preg_replace($arr,'',$str);
        return $str;
	}
	function safeParams(&$arr){
		if(is_array($arr)){
            foreach($arr as $k => $v){
                $arr[$k] = strip_tags(_safeParams($v));
            }
        }else{
            $arr = strip_tags(_safeParams($arr));
        }
        return $arr;
	}
	
    /* 检测全局变量设置（register globals）并移除他们 */
    function unregisterGlobals(){
       if (ini_get('register_globals')) {
           $array = array('_SESSION','_POST','_GET','_COOKIE','_REQUEST','_SERVER','_ENV','_FILES');
           foreach ($array as $value) {
               foreach ($GLOBALS[$value] as $key => $var) {
                  if ($var === $GLOBALS[$key]) {
                      unset($GLOBALS[$key]);
                  }
               }
           }
       }
    }
	
	//获取父类名称，$class = 类全名或ReflectionClass对象
	function get_parentClassName($class){
		if(is_string($class)){
			$class = new \ReflectionClass($class);
		}
		$pClass = $class->getParentClass();
		if($pClass){
			return get_parentClassName($pClass);
		}
		return $class->getName();
	}
	/**
	* IOC 方式产生实例,构造函数中的参数可以定义具体的类型，以便自动注入
	* $reflect = 类全名或ReflectionClass对象
	*/
	function create_class($reflect){
			//利用反射机制，模拟IOC
			if(is_string($reflect)) $reflect = new \ReflectionClass($reflect);
		   //没有构造函数
		   if($reflect->getConstructor()==null){
				$instance = $reflect->newInstance();
				return $instance;
		   }
		   //没有参数的构造函数
		   $constructArgs = $reflect->getConstructor()->getParameters();
		   if(count($constructArgs)==0) {
				$instance = $reflect->newInstance();
				return $instance;
		   }else{
				$params = create_method_params($reflect,$reflect->getConstructor()->getName());
				$instance = $reflect->newInstanceArgs($params);
				return $instance;
		   }
	}
	
	
	/**
	* IOC 方式产生方法参数实例,定义方法中可以定义具体的类型，以便自动注入
	* $reflect = ReflectionClass对象
	*/
	function create_method_params($refelct,$methodName){
		 $method = $refelct->getMethod($methodName);
		 $args = $method->getParameters();
		   if(count($args)==0) {
				return [];
		   }
		   else{
				//有参数的构造函数
				$params = array();
				foreach($args as $arg){
					if($arg->getClass()){
						$classFullName = $arg->getClass()->getName();
						//得到参数的实例
						$instance = create_class($classFullName);
						$params[] = $instance;
					}else{
						//必输参数
						if(!$arg->isOptional()){
							//有默认值，取默认值
							if($arg->isDefaultValueAvailable()){
								$instance = $arg->getDefaultValue();
							}else{
								$instance = null;
							}
							$params[] = $instance;
						}
					}
				}
				return $params;
		   }
	}
		   
		   
	//加载对应的Action
	function routeToAction(){
		if(isset($_GET['router'])){
			$router = $_GET['router'];
		}else{
			//主目录设置
			$router = HOME;
		}
		$uri = urldecode(
			parse_url($router, PHP_URL_PATH)
		);
		
		//url解析
		$pathArr = explode("/",$uri);
		$method = trim(array_pop($pathArr));
		$className = ucwords(trim(array_pop($pathArr))).'Action';
		$package = 'app\\action';
		if(count($pathArr)>0){
			$package .= '\\'.implode('\\',$pathArr);
		}
		$class = $package.'\\'.$className;
		
		$method = strtolower($_SERVER['REQUEST_METHOD']).ucwords($method);
		if ((int)method_exists($class, $method)) {
		   //调用之前，新进入action拦截器
		   global $APP_CONFIG;
		   if(count($APP_CONFIG['SYS_ACTION_BEFORE_FILTERS'])>0){
				foreach($APP_CONFIG['SYS_ACTION_BEFORE_FILTERS'] as $fname=>$fval){
				    $paths = implode('|',$fval['target_router']);
					$paths = '/'.preg_replace('/([^|]+)([|]?)/','($1)$2',$paths).'/';
					if(preg_match($paths,$uri)){
						//调用拦截器
						$_filter = $fval['class'];
						$_filterIance = new $_filter();
						if(!$_filterIance->doFilter(new \core\Request(),new \core\Response())){
							exit;			
						}
					}
				}
		   }
 
		  //$instance = new $class();
		  $reflect = new \ReflectionClass($class);
		  $instance = create_class($reflect);
		 
		  $methodParams = create_method_params($reflect,$method);
		  $methodParams[0]||$methodParams[0] = \core\App::form();
		  $methodParams[1]||$methodParams[1] = new \core\Request();
		  $methodParams[2]||$methodParams[2] = new \core\Response();
		  
		   //调用action方法
		   call_user_func_array(array($instance,$method),$methodParams);
		   //返回试图后被调用，一般用于做日记
		   if(count($APP_CONFIG['SYS_ACTION_AFTER_FILTERS'])>0){
				foreach($APP_CONFIG['SYS_ACTION_AFTER_FILTERS'] as $fname=>$fval){
				    $paths = implode('|',$fval['target_router']);
					$paths = '/'.preg_replace('/([^|]+)([|]?)/','($1)$2',$paths).'/';
					if(preg_match($paths,$uri)){
						//调用拦截器
						$_filter = $fval['class'];
						$_filterIance = new $_filter();
						$_filterIance->doFilter(new \core\Request(),new \core\Response());
					}
				}
		   }
		} else {
		   echo ROOT.DS.$class."@".$method." is not exist.";
		   exit;
		}
	}
	
	/*
	 * 精确时间间隔函数
	 * $time 发布时间 如 1356973323
	 * $str 输出格式 如 Y-m-d H:i:s
	 * 半年的秒数为15552000，1年为31104000，此处用半年的时间
	 */
	function format_time($time,$str="Y-m-d H:i:s"){
		isset($str)?$str:$str='m-d';
		$way = time() - $time;
		$r = '';
		if($way < 60){
			$r = '刚刚';
		}elseif($way >= 60 && $way <3600){
			$r = floor($way/60).'分钟前';
		}elseif($way >=3600 && $way <86400){
			$r = floor($way/3600).'小时前';
		}elseif($way >=86400 && $way <2592000){
			$r = floor($way/86400).'天前';
		}elseif($way >=2592000 && $way <15552000){
			$r = floor($way/2592000).'个月前';
		}else{
			$r = date("$str",$time);
		}
		return $r;
	}

	setReporting();
    unregisterGlobals();
	
	//自动登陆,免密码
	if($APP_CONFIG['REMEMBER_PWD']&&\core\App::session('user')==null){
		$login_name = \core\App::cookie('login_name');
		$login_pwd = \core\App::cookie('login_pwd');
		if(!empty($login_name)&&!empty($login_pwd)){
			$userAct = new \app\action\admin\UserAction();
			$userAct->postLogin(['autoLogin'=>true,'login_name'=>$login_name,'login_pwd'=>$login_pwd],new \core\Request());
		}
	}
	